#property copyright "Copyright 2012"
#property link      "mingxinhe@gmail.com"

#property indicator_chart_window
#property indicator_buffers 8

//Open. Close . High. Low. HL/2. HLC/3. HLCC/4
extern string Price.Type.Desc = "0:PRICE_CLOSE;1:PRICE_OPEN;2:PRICE_HIGH;3:PRICE_LOW;4:HL/2;5:HLC/3;6:HLCC/4";
extern int Price.Type = 0;
extern int Area.Dif.Pips = 5;

int digitFactor = 1;

double dotPrice[9];

double AreaBuffer[];

double A2Buffer[];
double A3Buffer[];
double B1Buffer[];
double B2Buffer[];
double B3Buffer[];
double C1Buffer[];
double C2Buffer[];

int A[201]={
20970,20870,20770,20670,20570,20470,20370,20270,20170,20070,19970,19870,19770,
19670,19570,19470,19370,19270,19170,19070,18970,18870,18770,18670,18570,18470,
18370,18270,18170,18070,17970,17870,17770,17670,17570,17470,17370,17270,17170,
17070,16970,16870,16770,16670,16570,16470,16370,16270,16170,16070,15970,15870,
15770,15670,15570,15470,15370,15270,15170,15070,14970,14870,14770,14670,14570,
14470,14370,14270,14170,14070,13970,13870,13770,13670,13570,13470,13370,13270,
13170,13070,12970,12870,12770,12670,12570,12470,12370,12270,12170,12070,11970,
11870,11770,11670,11570,11470,11370,11270,11170,11070,10970,10870,10770,10670,
10570,10470,10370,10270,10170,10070,9970,9870,9770,9670,9570,9470,9370,9270,
9170,9070,8970,8870,8770,8670,8570,8470,8370,8270,8170,8070,7970,7870,7770,
7670,7570,7470,7370,7270,7170,7070,6970,6870,6770,6670,6570,6470,6370,6270,
6170,6070,5970,5870,5770,5670,5570,5470,5370,5270,5170,5070,4970,4870,4770,
4670,4570,4470,4370,4270,4170,4070,3970,3870,3770,3670,3570,3470,3370,3270,
3170,3070,2970,2870,2770,2670,2570,2470,2370,2270,2170,2070,1970,1870,1770,
1670,1570,1470,1370,1270,1170,1070,970};

int B[201]={21000,20900,20800,20700,20600,20500,20400,20300,20200,20100,20000,19900,19800,

19700,19600,19500,19400,19300,19200,19100,19000,18900,18800,18700,18600,18500,18400,18300

,18200,18100,18000,17900,17800,17700,17600,17500,17400,17300,17200,17100,17000,16900,16800,

16700,16600,16500,16400,16300,16200,16100,16000,15900,15800,15700,15600,15500,15400,15300,

15200,15100,15000,14900,14800,14700,14600,14500,14400,14300,14200,14100,14000,13900,13800,13700,

13600,13500,13400,13300,13200,13100,13000,12900,12800,12700,12600,12500,12400,12300,12200,12100,

12000,11900,11800,11700,11600,11500,11400,11300,11200,11100,11000,10900,10800,10700,10600,10500,

10400,10300,10200,10100,10000,9900,9800,9700,9600,9500,9400,9300,9200,9100,9000,8900,8800,8700

,8600,8500,8400,8300,8200,8100,8000,7900,7800,7700,7600,7500,7400,7300,7200,7100,7000,6900,6800

,6700,6600,6500,6400,6300,6200,6100,6000,5900,5800,5700,5600,5500,5400,5300,5200,5100,5000,4900,

4800,4700,4600,4500,4400,4300,4200,4100,4000,3900,3800,3700,3600,3500,3400,3300,3200,3100,3000,

2900,2800,2700,2600,2500,2400,2300,2200,2100,2000,1900,1800,1700,1600,1500,1400,1300,1200,1100,1000};

int C[201]={
21030,20930,20830,20730,20630,20530,20430,20330,20230,20130,20030,19930,19830,
19730,19630,19530,19430,19330,19230,19130,19030,18930,18830,18730,18630,18530,
18430,18330,18230,18130,18030,17930,17830,17730,17630,17530,17430,17330,17230,
17130,17030,16930,16830,16730,16630,16530,16430,16330,16230,16130,16030,15930,
15830,15730,15630,15530,15430,15330,15230,15130,15030,14930,14830,14730,14630,
14530,14430,14330,14230,14130,14030,13930,13830,13730,13630,13530,13430,13330,
13230,13130,13030,12930,12830,12730,12630,12530,12430,12330,12230,12130,12030,
11930,11830,11730,11630,11530,11430,11330,11230,11130,11030,10930,10830,10730,
10630,10530,10430,10330,10230,10130,10030,9930,9830,9730,9630,9530,9430,9330,
9230,9130,9030,8930,8830,8730,8630,8530,8430,8330,8230,8130,8030,7930,7830,
7730,7630,7530,7430,7330,7230,7130,7030,6930,6830,6730,6630,6530,6430,6330,
6230,6130,6030,5930,5830,5730,5630,5530,5430,5330,5230,5130,5030,4930,4830,
4730,4630,4530,4430,4330,4230,4130,4030,3930,3830,3730,3630,3530,3430,3330,
3230,3130,3030,2930,2830,2730,2630,2530,2430,2330,2230,2130,2030,1930,1830,
1730,1630,1530,1430,1330,1230,1130,1030} ;

int init()
{
  //---- 6 additional buffers are used for counting.   
   if(Bid<10 && Digits==5) { digitFactor=10;}
   if(Bid<10 && Digits==4) { digitFactor= 1;}

   if(Bid>10 && Digits==3) { digitFactor=10;}
   if(Bid>10 && Digits==2) { digitFactor= 1;} 
   
   Area.Dif.Pips *= digitFactor;
   
   IndicatorBuffers(8);   
   IndicatorDigits(Digits);
//---- drawing settings 
   SetIndexStyle(0,DRAW_NONE);
   SetIndexStyle(1,DRAW_NONE);
   SetIndexStyle(2,DRAW_NONE);
   SetIndexStyle(3,DRAW_NONE);
   SetIndexStyle(4,DRAW_NONE);
   SetIndexStyle(5,DRAW_NONE);
   SetIndexStyle(6,DRAW_NONE);
   SetIndexStyle(7,DRAW_NONE);
   
   /*
   SetIndexStyle(0,DRAW_ARROW);
   SetIndexStyle(1,DRAW_ARROW);
   SetIndexStyle(2,DRAW_ARROW);
   SetIndexStyle(3,DRAW_ARROW);
   SetIndexStyle(4,DRAW_ARROW);
   SetIndexStyle(5,DRAW_ARROW);
   SetIndexStyle(6,DRAW_ARROW);
   SetIndexStyle(7,DRAW_NONE);
   
   SetIndexArrow(0,159);
   SetIndexArrow(1,159);
   SetIndexArrow(2,159);
   SetIndexArrow(3,159);
   SetIndexArrow(4,159);
   SetIndexArrow(5,159);
   SetIndexArrow(6,159);
   */
   
   SetIndexBuffer(0,A2Buffer); 
   SetIndexBuffer(1,A3Buffer); 
   SetIndexBuffer(2,B1Buffer); 
   SetIndexBuffer(3,B2Buffer); 
   SetIndexBuffer(4,B3Buffer); 
   SetIndexBuffer(5,C1Buffer); 
   SetIndexBuffer(6,C2Buffer);    
   SetIndexBuffer(7,AreaBuffer);   
}

int deinit()
{    
   for(int i = ObjectsTotal() - 1; i >= 0; i--)
   {
      string label = ObjectName(i);
      if(StringFind(label, "Dot") >=0)
      {    
          ObjectDelete(label);   
      }
   }    
   return(0);
}

//+------------------------------------------------------------------+
//| Moving Averages Convergence/Divergence                           |
//+------------------------------------------------------------------+
int start()
{  
   if(Bars<=10) return(0);
   
   int counted_bars=IndicatorCounted();        
   if(counted_bars>0) 
   {
       int limit=Bars-counted_bars;
   }
   else
   {
       limit = Bars-10+1;
   }       
      
   while(limit>=0)         
   {                        
      double searchPrice;         
      switch (Price.Type)
      {
          case 0: searchPrice = Close[limit]; break;      
          case 1: searchPrice = Open[limit]; break; 
          case 2: searchPrice = High[limit]; break; 
          case 3: searchPrice = Low[limit]; break; 
          case 4: searchPrice = (High[limit] + Low[limit])/2; break; 
          case 5: searchPrice = (High[limit] + Low[limit] + Close[limit])/3; break;    
          case 6: searchPrice = (High[limit] + Low[limit] + Close[limit] + Close[limit])/4; break; 
      }

      double oriSearchPrice = searchPrice;
      searchPrice *= MathPow(10, Digits);

      int divDigit = 0;
      while(searchPrice > A[0])
      {
          searchPrice /= 10;
          divDigit ++;
      }

      loopArray(searchPrice, A, 0);
      loopArray(searchPrice, B, 3);
      loopArray(searchPrice, C, 6);

      ArraySort(dotPrice, WHOLE_ARRAY,0,MODE_DESCEND);

      for (int i = 0; i < 9; i++)
      {
          dotPrice[i] /= MathPow(10, Digits - divDigit);                    
      }
      
      A2Buffer[limit] = dotPrice[1];
      A3Buffer[limit] = dotPrice[2];
      B1Buffer[limit] = dotPrice[3];
      B2Buffer[limit] = dotPrice[4];
      B3Buffer[limit] = dotPrice[5];
      C1Buffer[limit] = dotPrice[6];
      C2Buffer[limit] = dotPrice[7];
           
      //if (limit == 0)
      {
         drawArrow("A1_Dot" + TimeToStr(Time[limit]), limit, Yellow, 159, dotPrice[0]); 
         drawArrow("B1_Dot" + TimeToStr(Time[limit]), limit, Yellow, 159, dotPrice[1]); 
         drawArrow("C1_Dot" + TimeToStr(Time[limit]), limit, Yellow, 159, dotPrice[2]); 
         drawArrow("A2_Dot" + TimeToStr(Time[limit]), limit, Yellow, 159, dotPrice[3]); 
         drawArrow("B2_Dot" + TimeToStr(Time[limit]), limit, Yellow, 159, dotPrice[4]); 
         drawArrow("C2_Dot" + TimeToStr(Time[limit]), limit, Yellow, 159, dotPrice[5]); 
         drawArrow("A3_Dot" + TimeToStr(Time[limit]), limit, Yellow, 159, dotPrice[6]); 
         drawArrow("B3_Dot" + TimeToStr(Time[limit]), limit, Yellow, 159, dotPrice[7]); 
         drawArrow("C3_Dot" + TimeToStr(Time[limit]), limit, Yellow, 159, dotPrice[8]); 
          /*
         DrawHLine("A1_HLine",  dotPrice[0], HLineColor, HLineWidth, STYLE_DOT); 
         drawComments("A1_HLine_Label", dotPrice[0], "A[1]");
         DrawHLine("B1_HLine",  dotPrice[1], HLineColor, HLineWidth, STYLE_DOT); 
         drawComments("B1_HLine_Label", dotPrice[1], "B[1]");
         DrawHLine("C1_HLine",  dotPrice[2], HLineColor, HLineWidth, STYLE_DOT); 
         drawComments("C1_HLine_Label", dotPrice[2], "C[1]");
         DrawHLine("A2_HLine",  dotPrice[3], HLineColor, HLineWidth, STYLE_DOT); 
         drawComments("A2_HLine_Label", dotPrice[3], "A[2]");
         DrawHLine("B2_HLine",  dotPrice[4], HLineColor, HLineWidth, STYLE_DOT); 
         drawComments("B2_HLine_Label", dotPrice[4], "B[2]");
         DrawHLine("C2_HLine",  dotPrice[5], HLineColor, HLineWidth, STYLE_DOT); 
         drawComments("C2_HLine_Label", dotPrice[5], "C[2]");
         DrawHLine("A3_HLine",  dotPrice[6], HLineColor, HLineWidth, STYLE_DOT); 
         drawComments("A3_HLine_Label", dotPrice[6], "A[3]");
         DrawHLine("B3_HLine",  dotPrice[7], HLineColor, HLineWidth, STYLE_DOT); 
         drawComments("B3_HLine_Label", dotPrice[7], "B[3]");
         DrawHLine("C3_HLine",  dotPrice[8], HLineColor, HLineWidth, STYLE_DOT);  
         drawComments("C3_HLine_Label", dotPrice[8], "C[3]");
         */
      }               

      if (oriSearchPrice > dotPrice[3] + Area.Dif.Pips*Point)
      {
          AreaBuffer[limit] = 1;
      }
      else if (oriSearchPrice <= dotPrice[3] && oriSearchPrice >= dotPrice[5])
      {
          AreaBuffer[limit] = 2;       
      } 
      else if (oriSearchPrice < dotPrice[5] - Area.Dif.Pips*Point)
      {
          AreaBuffer[limit] = 3;
      }
      
      limit--;
  }
}

void loopArray(double searchPrice, int & array[], int dotArrayIdx)
{
   for (int i = 0; i <= 200; i++)
   {
      if (searchPrice > array[i])
      {
          break;
      }
   }

   dotPrice[dotArrayIdx] = array[i-1];
   dotPrice[dotArrayIdx + 1] = array[i];   

   if (A[i-2] - searchPrice < searchPrice - array[i+1])
   {
      dotPrice[dotArrayIdx + 2] = array[i-2];
   } 
   else
   {
      dotPrice[dotArrayIdx + 2] = array[i+1];
   } 
}

void DrawHLine(string name,  double y1, color lineColor, double lineWidth, double style)
{   
   if (ObjectFind(name) != 0)
   {
       ObjectCreate(name, OBJ_HLINE, 0, Time[0], y1);
       ObjectSet(name,OBJPROP_COLOR, lineColor);   
       ObjectSet(name,OBJPROP_STYLE, style);
       ObjectSet(name,OBJPROP_WIDTH, lineWidth); 
   }
   else
   {
       ObjectSet (name, OBJPROP_TIME1, Time [0]);
       ObjectSet (name, OBJPROP_PRICE1, y1); 
   } 
}

void drawArrow(string name, int barIdx, color arrowColor, int arrowCode, double price)
{       
   
   if (ObjectFind(name) != 0)
   {
       ObjectCreate(name,OBJ_ARROW,0,Time[barIdx],price);
       ObjectSet(name,OBJPROP_ARROWCODE,arrowCode);
       ObjectSet(name,OBJPROP_COLOR, arrowColor);   
       ObjectSet(name,OBJPROP_WIDTH, 1);
   }
   else
   {
       ObjectSet (name, OBJPROP_TIME1, Time [barIdx]);
       ObjectSet (name, OBJPROP_PRICE1, price); 
   }         
}


